package org.example.demo4;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Gong.Yang
 * 虚引用、引用队列使用
 * <p>
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
 */
@Slf4j
public class SoftReferenceDemo {
    static final int _4MB = 1024 * 1024 * 4;

    @SneakyThrows
    public static void main(String[] args) {
//        outOfmemoryReference();//内存溢出
        softReference();//有好几个null，说明内存不足时，软引用对象被释放了
    }

    private static void softReference() throws IOException {
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

        List<SoftReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
//            list.add(new SoftReference<>(new byte[_4MB]));
            list.add(new SoftReference<>(new byte[_4MB], queue));
        }
        log.info("【内容查看】");
        for (SoftReference<byte[]> softReference : list) {
            byte[] bytes = softReference.get();
            System.out.println(bytes);
        }

        log.info("【引用查看】弱引用清理前");
        for (SoftReference<byte[]> softReference : list) {
            System.out.println(softReference);
        }


        log.info("【清理弱引用】配合引用队列清理无用弱引用");
        Reference<? extends byte[]> poll = queue.poll();
        while (poll != null) {
            list.remove(poll);
            poll = queue.poll();
        }

        log.info("【引用查看】弱引用清理后");
        for (SoftReference<byte[]> softReference : list) {
            System.out.println(softReference);
        }
    }

    private static void outOfmemoryReference() throws IOException {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(new byte[_4MB]);
        }
        System.in.read();
    }
}
